package com.ymttest.business.service;

import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.json.JSONArray;
import org.json.JSONObject;

import com.ymatou.iapi.prodstock.parameter.OrderReturnCatalogDto;
import com.ymatou.iapi.prodstock.parameter.OrderReturnCatalogDto.CatalogStockListDto;
import com.ymatou.iapi.prodstock.parameter.PreOrderReduceCatalogDto;
import com.ymatou.iapi.prodstock.parameter.PreOrderReduceCatalogDto.CatalogListDto;
import com.ymatou.iapi.prodstock.service.ReduceStockListForPreOrderCall;
import com.ymatou.iapi.prodstock.service.ReturnProductStockForOrderCall;
import com.ymatou.iapi.prodstock.service.ReturnStockListForRefundBillCall;
import com.ymt.base.BaseBean;
import com.ymt.core.tool.Logger;
import com.ymttest.database.model.YmtActivityStockRecord;
import com.ymttest.database.model.YmtCatalogsI;
import com.ymttest.database.model.YmtPreOrderStockLog;
import com.ymttest.database.model.YmtProductActivityStock;
import com.ymttest.database.model.YmtProductOrderStockLog;
import com.ymttest.database.model.YmtProductsInActivity;
import com.ymttest.database.model.YmtStockChangeDetail;
import com.ymttest.database.mongo.YmtMongoDriverFactroy;
import com.ymttest.database.mongo.jproduct.ActivityProductsWapper;
import com.ymttest.database.mongo.jproduct.CatalogsWapper;
import com.ymttest.database.sqlwapper.BusinessCredentialInfoWapper;
import com.ymttest.database.sqlwapper.YmtActivityStockRecordWapper;
import com.ymttest.database.sqlwapper.YmtActivityWapper;
import com.ymttest.database.sqlwapper.YmtCatalogsIWapper;
import com.ymttest.database.sqlwapper.YmtPreOrderStockLogWapper;
import com.ymttest.database.sqlwapper.YmtProductActivityStockWapper;
import com.ymttest.database.sqlwapper.YmtProductOrderStockLogWapper;
import com.ymttest.database.sqlwapper.YmtProductsInActivityWapper;
import com.ymttest.database.sqlwapper.YmtStockChangeDetailWapper;
import com.ymttest.utils.MapUtil;
import com.ymttest.utils.TestDataManager;
import com.ymttest.utils.YMTDateUtil;

public class ProdStockCallService {
	//=========================================================================
	//扣库存
	public static PreOrderReduceCatalogDto.CatalogListDto ReduceStockListForPreOrder(String productId, String catalogId,int sellerId,
			int activityId,int buyCount,int catalogType,boolean checkRetStatus) throws Exception{
		return ReduceStockListForPreOrder( productId,  catalogId, sellerId,
				 activityId, buyCount, catalogType, Math.abs(TestDataManager.getRandomIntNum(4)), checkRetStatus);
	}
	
	public static PreOrderReduceCatalogDto.CatalogListDto ReduceStockListForPreOrder(String productId, String catalogId,int sellerId,
			int activityId,int buyCount,int catalogType,int buyId,boolean checkRetStatus) throws Exception{
		return ReduceStockListForPreOrder( productId,  catalogId, sellerId,
				 activityId, buyCount, catalogType,   buyId,getCurrentOrderId(),checkRetStatus);
	}
	public static PreOrderReduceCatalogDto.CatalogListDto ReduceStockListForPreOrder(String productId, String catalogId,int sellerId,
			int activityId,int buyCount,int catalogType,int buyId,long orderId,boolean checkRetStatus) throws Exception{
		return ReduceStockListForPreOrder( productId,  catalogId, sellerId,
				 activityId, buyCount, catalogType,   buyId,getCurrentOrderId(),checkRetStatus,false);
	}
	
	
	
	public static List<CatalogListDto> ReduceStockListForPreOrder(List<CatalogListDto> catalogListDto,boolean checkRetStatus,boolean isIdempotent) throws Exception{
		BusinessCredentialInfoWapper businessCredentialInfoWapper = new BusinessCredentialInfoWapper();
		Map<String,Integer> ActivityStockChange_CountMap = new HashMap<>();
		Map<String,Integer> CatalogStockChange_CountMap = new HashMap<>();
		
		
		
		PreOrderReduceCatalogDto preOrderReduceCatalogDto = new PreOrderReduceCatalogDto();
		preOrderReduceCatalogDto.setCatalogList(catalogListDto);
		
		int tmpBuyId = Math.abs(TestDataManager.getRandomIntNum(4));
		
		catalogListDto.forEach(catalogDto->{
			//如果没有orderid 随机生成id
			if (catalogDto.getPreOrderId()==0){catalogDto.setPreOrderId(getCurrentOrderId());}
			
			if(catalogDto.getBuyerId()==0){catalogDto.setBuyerId(tmpBuyId);}
			
			//存放凭据表记录
			try {
				ActivityStockChange_CountMap.put(catalogDto.getProductId(),
						businessCredentialInfoWapper.selectByProductIdAndType(catalogDto.getProductId(),"ActivityStockChange").size());
				
				CatalogStockChange_CountMap.put(catalogDto.getProductId(),
						businessCredentialInfoWapper.selectByProductIdAndType(catalogDto.getProductId(),"CatalogStockChange").size());
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		});
		
		JSONObject ret = new ReduceStockListForPreOrderCall().callAndGetReturnData(preOrderReduceCatalogDto);
		if (checkRetStatus){
			Logger.verifyEquals(checkRetStatus, ret.getJSONObject("Data").getBoolean("ReduceStatus"), "ReduceStockListForPreOrder 返回值检查");
			Logger.verifyEquals(200, ret.getInt("Code"), "扣单成功，code应为200");
		}else{
			Logger.verifyEquals(true, ret.isNull("Data"), "扣单失败,data为null");
			Logger.verifyEquals(201, ret.getInt("Code"), "扣单失败，code应为201");
		}
		
		
		
		//凭据表检查
		catalogListDto.forEach(catalogDto->{
			String productId = catalogDto.getProductId();
			try{
				if (catalogDto.getActivityId()>0){
					//一条是活动审核，一条是扣库存
					if (checkRetStatus){
						if (isIdempotent){
							Logger.verifyEquals(ActivityStockChange_CountMap.get(productId)
									,businessCredentialInfoWapper.selectByProductIdAndType(productId,"ActivityStockChange").size(),
									"SQL-BusinessCredentialInfo 业务凭据表检查ActivityStockChange 幂等不增加记录");
						}else{
							Logger.verifyEquals(ActivityStockChange_CountMap.get(productId)+1
									,businessCredentialInfoWapper.selectByProductIdAndType(productId, "ActivityStockChange").size(),
									"SQL-BusinessCredentialInfo 业务凭据表检查ActivityStockChange");
						}
						
					}else{
						Logger.verifyEquals(ActivityStockChange_CountMap.get(productId),
								businessCredentialInfoWapper.selectByProductIdAndType(productId, "ActivityStockChange").size(),
								"SQL-BusinessCredentialInfo 下单失败，业务凭据表检查ActivityStockChange");
					}
				}else{
					if (checkRetStatus){
						if(isIdempotent ){
							Logger.verifyEquals(CatalogStockChange_CountMap.get(productId),
									businessCredentialInfoWapper.selectByProductIdAndType(productId, "CatalogStockChange").size(),
									"SQL-BusinessCredentialInfo 业务凭据表检查CatalogStockChange 幂等不增加记录");
						}else{
							Logger.verifyEquals(CatalogStockChange_CountMap.get(productId)+1,
									businessCredentialInfoWapper.selectByProductIdAndType(productId, "CatalogStockChange").size(),
									"SQL-BusinessCredentialInfo 业务凭据表检查CatalogStockChange");
						}
						
					}else{
						Logger.verifyEquals(CatalogStockChange_CountMap.get(productId),
								businessCredentialInfoWapper.selectByProductIdAndType(productId, "CatalogStockChange").size(),
								"SQL-BusinessCredentialInfo 下单失败，业务凭据表检查CatalogStockChange");
					}
				}
			}catch(Exception e){
				Logger.fail(e);
			}
		});
		
		return catalogListDto;
		
	}
	
	
	/***
	 * 扣库存
	 * @param productId
	 * @param catalogId
	 * @param sellerId
	 * @param activityId
	 * @param buyCount
	 * @param catalogType
	 * @param buyId
	 * @param orderId
	 * @param checkRetStatus 是否扣单成功
	 * @param isIdempotent	是否是个幂等请求
	 * @return
	 * @throws Exception
	 */
	public static PreOrderReduceCatalogDto.CatalogListDto ReduceStockListForPreOrder(String productId, String catalogId,int sellerId,
							int activityId,int buyCount,int catalogType,int buyId,long orderId,boolean checkRetStatus,boolean isIdempotent ) throws Exception{
		PreOrderReduceCatalogDto preOrderReduceCatalogDto = new PreOrderReduceCatalogDto();
		PreOrderReduceCatalogDto.CatalogListDto  catalogListDto = new PreOrderReduceCatalogDto.CatalogListDto();
		
		BusinessCredentialInfoWapper businessCredentialInfoWapper = new BusinessCredentialInfoWapper();
		int ActivityStockChange_Count = businessCredentialInfoWapper.selectByProductIdAndType(productId, "ActivityStockChange").size();
		int CatalogStockChange_Count = businessCredentialInfoWapper.selectByProductIdAndType(productId, "CatalogStockChange").size();
		
		
		
		catalogListDto.setIsLiveProduct(false);
		catalogListDto.setActivityId(activityId);
		catalogListDto.setBuyerId(buyId);
		catalogListDto.setCatalogId(catalogId);
		catalogListDto.setCatalogType(catalogType);
		catalogListDto.setPreOrderId(orderId);
		catalogListDto.setProductId(productId);
		catalogListDto.setSellerId(sellerId);
		catalogListDto.setBuyCount(buyCount);
		catalogListDto.setProductLimitNumber(0);
		catalogListDto.setProductLimitStartTime(new Date());
		catalogListDto.setActivityLimitNumber(0);
		preOrderReduceCatalogDto.setCatalogList(Arrays.asList(catalogListDto));

		JSONObject ret = new ReduceStockListForPreOrderCall().callAndGetReturnData(preOrderReduceCatalogDto);
		if (checkRetStatus){
			Logger.verifyEquals(checkRetStatus, ret.getJSONObject("Data").getBoolean("ReduceStatus"), "ReduceStockListForPreOrder 返回值检查");
			Logger.verifyEquals(200, ret.getInt("Code"), "扣单成功，code应为200");
		}else{
			Logger.verifyEquals(true, ret.isNull("Data"), "扣单失败,data为null");
			Logger.verifyEquals(201, ret.getInt("Code"), "扣单失败，code应为201");
		}
		
		

		//业务凭据表检查
		if (activityId>0){
			//一条是活动审核，一条是扣库存
			if (checkRetStatus){
				if (isIdempotent){
					Logger.verifyEquals(ActivityStockChange_Count,businessCredentialInfoWapper.selectByProductIdAndType(catalogListDto.getProductId(), "ActivityStockChange").size(),
							"SQL-BusinessCredentialInfo 业务凭据表检查ActivityStockChange 幂等不增加记录");
				}else{
					Logger.verifyEquals(ActivityStockChange_Count+1,businessCredentialInfoWapper.selectByProductIdAndType(catalogListDto.getProductId(), "ActivityStockChange").size(),
							"SQL-BusinessCredentialInfo 业务凭据表检查ActivityStockChange");
				}
				
			}else{
				Logger.verifyEquals(ActivityStockChange_Count,businessCredentialInfoWapper.selectByProductIdAndType(catalogListDto.getProductId(), "ActivityStockChange").size(),
						"SQL-BusinessCredentialInfo 下单失败，业务凭据表检查ActivityStockChange");
			}
		}else{
			if (checkRetStatus){
				if(isIdempotent ){
					Logger.verifyEquals(CatalogStockChange_Count,businessCredentialInfoWapper.selectByProductIdAndType(catalogListDto.getProductId(), "CatalogStockChange").size(),
							"SQL-BusinessCredentialInfo 业务凭据表检查CatalogStockChange 幂等不增加记录");
				}else{
					Logger.verifyEquals(CatalogStockChange_Count+1,businessCredentialInfoWapper.selectByProductIdAndType(catalogListDto.getProductId(), "CatalogStockChange").size(),
							"SQL-BusinessCredentialInfo 业务凭据表检查CatalogStockChange");
				}
				
			}else{
				Logger.verifyEquals(CatalogStockChange_Count,businessCredentialInfoWapper.selectByProductIdAndType(catalogListDto.getProductId(), "CatalogStockChange").size(),
					"SQL-BusinessCredentialInfo 下单失败，业务凭据表检查CatalogStockChange");
			}
		}
	
		
		
		
		return preOrderReduceCatalogDto.getCatalogList().get(0);
	
	
	}
	
	public static void checkReduceStock(CatalogListDto catalogListDto,int expectedStock, int expectedActivityStock) throws Exception{
		checkReduceStock(catalogListDto,expectedStock,expectedActivityStock,true);
	}
	
	
	public static void checkReduceStock(CatalogListDto catalogListDto,int expectedStock, int expectedActivityStock,boolean reduceSuccess) throws Exception{
		//sql
		//check ymt_catalogId inum
		YmtCatalogsIWapper ymtCatalogsIWapper = new YmtCatalogsIWapper();
		YmtCatalogsI catalogInSql = ymtCatalogsIWapper.selectCatalogsByCatalogId(catalogListDto.getCatalogId());
		Logger.verifyEquals(expectedStock, catalogInSql.getiNum(),  "SQL-Ymt_Catalogs 商品库存数量");
		
		
		//sql 日志检查
		//check YmtProductOrderStockLog
		List<YmtProductOrderStockLog> ymtProductOrderStockLogList = new YmtProductOrderStockLogWapper().selectByOrderId(catalogListDto.getPreOrderId());
		
		//check YmtPreOrderStockLogWapper
		List<YmtPreOrderStockLog> ymtPreOrderStockLogList = new YmtPreOrderStockLogWapper().selectByPreOrderId(catalogListDto.getPreOrderId());
	
		if (reduceSuccess){
			Logger.verifyEquals(1, ymtProductOrderStockLogList.size(), "SQL-Ymt_ProductOrderStockLog 应该有一条记录");
			Logger.verifyEquals( -1*catalogListDto.getBuyCount(),ymtProductOrderStockLogList.get(0).getStockNum(), "SQL-Ymt_ProductOrderStockLog stock 检查");
			Logger.verifyEquals(catalogListDto.getBuyerId(),ymtProductOrderStockLogList.get(0).getBuyerId(),  "SQL-Ymt_ProductOrderStockLog buyId 检查");
			if (catalogListDto.getActivityId()>0){
				Logger.verifyEquals(catalogListDto.getActivityId(),ymtProductOrderStockLogList.get(0).getActivityId(), "SQL-Ymt_ProductOrderStockLog activityId 检查");
			}else{
				Logger.verifyEquals(0,ymtProductOrderStockLogList.get(0).getActivityId(), "SQL-Ymt_ProductOrderStockLog activityId 检查");
			}
			
			
			Logger.verifyEquals(1, ymtPreOrderStockLogList.size(), "SQL-YmtPreOrderStockLog 应该有一条记录");
			Logger.verifyEquals(-1, ymtPreOrderStockLogList.get(0).getOperType(), "SQL-YmtPreOrderStockLog operType应该为-1");
			
			
		}else{
			Logger.verifyEquals(0, ymtProductOrderStockLogList.size(), "YmtProductOrderStockLog - 下单失败不应有记录");
			Logger.verifyEquals(0, ymtPreOrderStockLogList.size(),"YmtPreOrderStockLogWapper - 下单失败不应有记录");
		}
		
		
	
		
		
		//普通贝海商品 检查在途库存 Ymt_StockChangeDetail
		if (catalogListDto.getCatalogType()==2&&catalogListDto.getActivityId()==0){
			YmtStockChangeDetailWapper ymtStockChangeDetailWapper = new YmtStockChangeDetailWapper();
			List<YmtStockChangeDetail> ymtStockChangeDetailList = ymtStockChangeDetailWapper.selectByCatalogId(catalogListDto.getCatalogId());
			Logger.verifyEquals(1, ymtStockChangeDetailList.size(),"SQL-Ymt_StockChangeDetail 记录个数应有1条");
			Logger.verifyEquals(catalogListDto.getBuyCount(), ymtStockChangeDetailList.get(0).getiStock(), "SQL-Ymt_StockChangeDetail stock");
			Logger.verifyEquals(catalogInSql.getsSKU(), ymtStockChangeDetailList.get(0).getsSKU(), "SQL-Ymt_StockChangeDetail sku");
		}
	
		
		
		//活动商品
		if (catalogListDto.getActivityId()>0){
			YmtProductActivityStockWapper ymtProductActivityStockWapper = new YmtProductActivityStockWapper();
			YmtProductActivityStock ymtProductActivityStock = ymtProductActivityStockWapper.selectByCatalogId(catalogListDto.getCatalogId());
			Logger.verifyEquals(expectedActivityStock, ymtProductActivityStock.getIstocknum(), "SQL-YmtProductActivityStock stock 检查");
			Logger.verifyEquals(catalogListDto.getActivityId(),ymtProductActivityStock.getIactivityid(), "SQL-YmtProductActivityStock activityId 检查");
		
		}
		
		
		
		
		//=======================================================================
		//mongo 检查
		checkStockInMgo(catalogListDto.getCatalogId(),catalogListDto.getActivityId(),expectedStock,expectedActivityStock);
		
		//es check
		EsProductCallService.checkEsProduct(catalogListDto.getProductId());
		
	}
	
	
	
	
	//=========================================================================
	public static List<OrderReturnCatalogDto.CatalogStockListDto> BackStock(List<CatalogStockListDto> catalogStockListDto,
			boolean checkRetStatus, boolean isIdempotent,Function<BaseBean,JSONObject> callApi) throws Exception{
		
		BusinessCredentialInfoWapper businessCredentialInfoWapper = new BusinessCredentialInfoWapper();
		Map<String,Integer> ActivityStockChange_CountMap = new HashMap<>();
		Map<String,Integer> CatalogStockChange_CountMap = new HashMap<>();
		
		int tmpBuyId = Math.abs(TestDataManager.getRandomIntNum(4));
		
		catalogStockListDto.forEach(catalogStockDto->{
			if (catalogStockDto.getOrderId()==0){catalogStockDto.setOrderId(getCurrentOrderId());}
			
			if (catalogStockDto.getBuyerId()==0){catalogStockDto.setBuyerId(tmpBuyId);}
			
			if (catalogStockDto.getRefundBillNo()==0){catalogStockDto.setRefundBillNo(Math.abs(TestDataManager.getRandomIntNum(7)));}
			
			//存放凭据表记录
			try {
				ActivityStockChange_CountMap.put(catalogStockDto.getProductId(),
						businessCredentialInfoWapper.selectByProductIdAndType(catalogStockDto.getProductId(),"ActivityStockChange").size());
				
				CatalogStockChange_CountMap.put(catalogStockDto.getProductId(),
						businessCredentialInfoWapper.selectByProductIdAndType(catalogStockDto.getProductId(),"CatalogStockChange").size());
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		});
		
		
		//call api
		OrderReturnCatalogDto orderReturnCatalogDto = new OrderReturnCatalogDto();
		orderReturnCatalogDto.setCatalogStockList(catalogStockListDto);
		JSONObject ret = callApi.apply(orderReturnCatalogDto);
		
		//check return status 
		if (checkRetStatus){
			Logger.verifyEquals("ok", ret.getString("response"), callApi.getClass().getName()+"返回值检查");
		}else{
			Logger.verifyEquals("fail", ret.getString("response"),  callApi.getClass().getName()+"返回值检查");
		}
		
		
		catalogStockListDto.forEach(catalogStockDto->{
			String productId = catalogStockDto.getProductId();
			try{
				//业务凭据表检查
				if (catalogStockDto.getActivityId()>0){
					//一条是活动审核，一条是扣库存
					if (checkRetStatus){
						if (isIdempotent){
							Logger.verifyEquals(ActivityStockChange_CountMap.get(productId),
									businessCredentialInfoWapper.selectByProductIdAndType(productId, "ActivityStockChange").size(),
									"SQL-BusinessCredentialInfo 业务凭据表检查ActivityStockChange 幂等不增加记录");
						}else{
							YmtProductsInActivity ymtProductsInActivity = new YmtProductsInActivityWapper().selectByProductId(productId);
							//活动已结束
							if (ymtProductsInActivity.getDendtime().before(YMTDateUtil.getDate())){
								Logger.verifyEquals(CatalogStockChange_CountMap.get(productId)+1,
										businessCredentialInfoWapper.selectByProductIdAndType(productId, "CatalogStockChange").size(),
										"SQL-BusinessCredentialInfo 业务凭据表检查CatalogStockChange");
							}else{
								Logger.verifyEquals(ActivityStockChange_CountMap.get(productId)+1,
										businessCredentialInfoWapper.selectByProductIdAndType(productId, "ActivityStockChange").size(),
										"SQL-BusinessCredentialInfo 业务凭据表检查ActivityStockChange");
							}
						}
						
					}else{
						Logger.verifyEquals(ActivityStockChange_CountMap.get(productId),
								businessCredentialInfoWapper.selectByProductIdAndType(productId, "ActivityStockChange").size(),
								"SQL-BusinessCredentialInfo 下单失败，业务凭据表检查ActivityStockChange");
					}
				}else{
					if (checkRetStatus){
						if(isIdempotent ){
							Logger.verifyEquals(CatalogStockChange_CountMap.get(productId),
									businessCredentialInfoWapper.selectByProductIdAndType(productId, "CatalogStockChange").size(),
									"SQL-BusinessCredentialInfo 业务凭据表检查CatalogStockChange 幂等不增加记录");
						}else{
							Logger.verifyEquals(CatalogStockChange_CountMap.get(productId)+1,
									businessCredentialInfoWapper.selectByProductIdAndType(productId, "CatalogStockChange").size(),
									"SQL-BusinessCredentialInfo 业务凭据表检查CatalogStockChange");
						}
						
					}else{
						Logger.verifyEquals(CatalogStockChange_CountMap.get(productId),
								businessCredentialInfoWapper.selectByProductIdAndType(productId, "CatalogStockChange").size(),
							"SQL-BusinessCredentialInfo 下单失败，业务凭据表检查CatalogStockChange");
					}
				}
			}catch(Exception e){
				Logger.fail(e);
			}
		});
		
		
		
		
		
		
		
		
		return catalogStockListDto;
		
	}
	
	
	
	
	
	
	
	
	//返库存  ReturnProductStockForOrderCall 
	public static OrderReturnCatalogDto.CatalogStockListDto BackStock(CatalogStockListDto catalogStockListDto,
										boolean checkRetStatus, boolean isIdempotent,Function<BaseBean,JSONObject> callApi) throws Exception{
		BusinessCredentialInfoWapper businessCredentialInfoWapper = new BusinessCredentialInfoWapper();
		int ActivityStockChange_Count = businessCredentialInfoWapper.selectByProductIdAndType(catalogStockListDto.getProductId(), "ActivityStockChange").size();
		int CatalogStockChange_Count = businessCredentialInfoWapper.selectByProductIdAndType(catalogStockListDto.getProductId(), "CatalogStockChange").size();
		
		
		if (catalogStockListDto.getOrderId()==0){catalogStockListDto.setOrderId(getCurrentOrderId());}
		
		if (catalogStockListDto.getBuyerId()==0){catalogStockListDto.setBuyerId(Math.abs(TestDataManager.getRandomIntNum(4)));}
		
		OrderReturnCatalogDto orderReturnCatalogDto = new OrderReturnCatalogDto();
		orderReturnCatalogDto.setCatalogStockList(Arrays.asList(catalogStockListDto));
		
		JSONObject ret = callApi.apply(orderReturnCatalogDto);
		
		if (checkRetStatus){
			Logger.verifyEquals("ok", ret.getString("response"), callApi.getClass().getName()+"返回值检查");
		}else{
			Logger.verifyEquals("fail", ret.getString("response"),  callApi.getClass().getName()+"返回值检查");
		}
		
		
		//业务凭据表检查
		if (catalogStockListDto.getActivityId()>0){
			//一条是活动审核，一条是扣库存
			if (checkRetStatus){
				if (isIdempotent){
					Logger.verifyEquals(ActivityStockChange_Count,businessCredentialInfoWapper.selectByProductIdAndType(catalogStockListDto.getProductId(), "ActivityStockChange").size(),
							"SQL-BusinessCredentialInfo 业务凭据表检查ActivityStockChange 幂等不增加记录");
				}else{
					YmtProductsInActivity ymtProductsInActivity = new YmtProductsInActivityWapper().selectByProductId(catalogStockListDto.getProductId());
					//活动已结束
					if (ymtProductsInActivity.getDendtime().before(YMTDateUtil.getDate())){
						Logger.verifyEquals(CatalogStockChange_Count+1,businessCredentialInfoWapper.selectByProductIdAndType(catalogStockListDto.getProductId(), "CatalogStockChange").size(),
								"SQL-BusinessCredentialInfo 业务凭据表检查CatalogStockChange");
					}else{
						Logger.verifyEquals(ActivityStockChange_Count+1,businessCredentialInfoWapper.selectByProductIdAndType(catalogStockListDto.getProductId(), "ActivityStockChange").size(),
								"SQL-BusinessCredentialInfo 业务凭据表检查ActivityStockChange");
					}
				
				}
				
			}else{
				Logger.verifyEquals(ActivityStockChange_Count,businessCredentialInfoWapper.selectByProductIdAndType(catalogStockListDto.getProductId(), "ActivityStockChange").size(),
						"SQL-BusinessCredentialInfo 下单失败，业务凭据表检查ActivityStockChange");
			}
		}else{
			if (checkRetStatus){
				if(isIdempotent ){
					Logger.verifyEquals(CatalogStockChange_Count,businessCredentialInfoWapper.selectByProductIdAndType(catalogStockListDto.getProductId(), "CatalogStockChange").size(),
							"SQL-BusinessCredentialInfo 业务凭据表检查CatalogStockChange 幂等不增加记录");
				}else{
					Logger.verifyEquals(CatalogStockChange_Count+1,businessCredentialInfoWapper.selectByProductIdAndType(catalogStockListDto.getProductId(), "CatalogStockChange").size(),
							"SQL-BusinessCredentialInfo 业务凭据表检查CatalogStockChange");
				}
				
			}else{
				Logger.verifyEquals(CatalogStockChange_Count,businessCredentialInfoWapper.selectByProductIdAndType(catalogStockListDto.getProductId(), "CatalogStockChange").size(),
					"SQL-BusinessCredentialInfo 下单失败，业务凭据表检查CatalogStockChange");
			}
		}
			
				
		return catalogStockListDto;
	}
	
	//返库存  ReturnProductStockForOrderCall 
	public static OrderReturnCatalogDto.CatalogStockListDto ReturnProductStockForOrder(CatalogStockListDto catalogStockListDto) throws Exception{
			return ReturnProductStockForOrder(catalogStockListDto,true,false);
	}
	
	public static List<CatalogStockListDto> ReturnProductStockForOrder(List<CatalogStockListDto> catalogStockListDto) throws Exception{
		return BackStock(catalogStockListDto,true,false,x->new ReturnProductStockForOrderCall().callAndGetReturnData(x));
	}
	
	public static List<CatalogStockListDto> ReturnProductStockForOrder(List<CatalogStockListDto> catalogStockListDto,boolean checkRetStatus, boolean isIdempotent) throws Exception{
		return BackStock(catalogStockListDto,checkRetStatus,isIdempotent,x->new ReturnProductStockForOrderCall().callAndGetReturnData(x));
	}
	
	
	
	public static OrderReturnCatalogDto.CatalogStockListDto ReturnProductStockForOrder(CatalogStockListDto catalogStockListDto,boolean checkRetStatus, boolean isIdempotent)throws Exception{
		return BackStock(catalogStockListDto,checkRetStatus,isIdempotent,x->new ReturnProductStockForOrderCall().callAndGetReturnData(x));
	}
	
	
	
	//返库存  ReturnProductStockForOrderCall 
	public static List<CatalogStockListDto> ReturnStockListForRefundBill(List<CatalogStockListDto> catalogStockListDto) throws Exception{
		return BackStock(catalogStockListDto,true,false,x->new ReturnStockListForRefundBillCall().callAndGetReturnData(x));
	}
	
	public static List<CatalogStockListDto> ReturnStockListForRefundBill(List<CatalogStockListDto> catalogStockListDto,boolean checkRetStatus, boolean isIdempotent) throws Exception{
		return BackStock(catalogStockListDto,checkRetStatus,isIdempotent,x->new ReturnStockListForRefundBillCall().callAndGetReturnData(x));
	}
	
	
	
	public static OrderReturnCatalogDto.CatalogStockListDto ReturnStockListForRefundBill(CatalogStockListDto catalogStockListDto) throws Exception{
		return ReturnStockListForRefundBill(catalogStockListDto,true,false);
	}
		
	public static OrderReturnCatalogDto.CatalogStockListDto ReturnStockListForRefundBill(CatalogStockListDto catalogStockListDto,boolean checkRetStatus, boolean isIdempotent)throws Exception{
		return BackStock(catalogStockListDto,checkRetStatus,isIdempotent,x->new ReturnStockListForRefundBillCall().callAndGetReturnData(x));
	}
		
	
	
	public static void checkBackStock(CatalogStockListDto catalogStockListDto,int expectedStock, int expectedActivityStock,boolean returnSuccess,long orderId) throws Exception{
		//sql
		//check ymt_catalogId inum
		YmtCatalogsIWapper ymtCatalogsIWapper = new YmtCatalogsIWapper();
		YmtCatalogsI catalogInSql = ymtCatalogsIWapper.selectCatalogsByCatalogId(catalogStockListDto.getCatalogId());
		Logger.verifyEquals(expectedStock, catalogInSql.getiNum(),  "SQL-Ymt_Catalogs 商品库存数量");
		
		
		//sql 日志检查
		//check YmtProductOrderStockLog
		//List<YmtProductOrderStockLog> ymtProductOrderStockLogList = new YmtProductOrderStockLogWapper().selectByOrderId(orderId);
		
		//check YmtPreOrderStockLogWapper
		List<YmtPreOrderStockLog> ymtPreOrderStockLogList = new YmtPreOrderStockLogWapper().selectByLongPreOrderId(orderId);
		if (returnSuccess){
			Logger.verifyEquals(1, ymtPreOrderStockLogList.size(), "SQL-YmtPreOrderStockLog 应该有一条记录");
			Logger.verifyEquals(1, ymtPreOrderStockLogList.get(0).getOperType(), "SQL-YmtPreOrderStockLog operType应该为1");
		}else{
			Logger.verifyEquals(0, ymtPreOrderStockLogList.size(),"YmtPreOrderStockLogWapper - 下单失败不应有记录");
		}
		
		
		//普通贝海商品 检查在途库存 Ymt_StockChangeDetail
		if (catalogStockListDto.getCatalogType()==2&&catalogStockListDto.getActivityId()==0){
			List<YmtProductOrderStockLog> ymtProductOrderStockLogList1 = new YmtProductOrderStockLogWapper().selectByCatalogId(catalogStockListDto.getCatalogId());
			int sum_OrderNum = ymtProductOrderStockLogList1.stream().filter(x->x.getActivityId()==0).map(y->y.getStockNum()).collect(Collectors.summingInt(Integer::intValue));
		
			YmtStockChangeDetailWapper ymtStockChangeDetailWapper = new YmtStockChangeDetailWapper();
			List<YmtStockChangeDetail> ymtStockChangeDetailList = ymtStockChangeDetailWapper.selectByCatalogId(catalogStockListDto.getCatalogId());
			
			Logger.verifyEquals(1, ymtStockChangeDetailList.size(),"SQL-Ymt_StockChangeDetail 记录个数应有1条");
			Logger.verifyEquals(-1*sum_OrderNum, ymtStockChangeDetailList.get(0).getiStock(), "SQL-Ymt_StockChangeDetail stock");
			Logger.verifyEquals(catalogInSql.getsSKU(), ymtStockChangeDetailList.get(0).getsSKU(), "SQL-Ymt_StockChangeDetail sku");
		}
	
		
		
		//活动商品
		if (catalogStockListDto.getActivityId()>0){
			YmtProductActivityStockWapper ymtProductActivityStockWapper = new YmtProductActivityStockWapper();
			YmtProductActivityStock ymtProductActivityStock = ymtProductActivityStockWapper.selectByCatalogId(catalogStockListDto.getCatalogId());
			Logger.verifyEquals(expectedActivityStock, ymtProductActivityStock.getIstocknum(), "SQL-YmtProductActivityStock stock 检查");
			Logger.verifyEquals(catalogStockListDto.getActivityId(),ymtProductActivityStock.getIactivityid(), "SQL-YmtProductActivityStock activityId 检查");
		
			//Ymt_ActivityStockRecord 检查
			List<YmtActivityStockRecord> ymtActivityStockRecordList = new YmtActivityStockRecordWapper().
									selectByOrderIdAndProdInActivityId(catalogStockListDto.getOrderId(), ymtProductActivityStock.getIproductinactivityid());
			
			//Logger.verifyEquals(1, ymtActivityStockRecordList.size(), "Ymt_ActivityStockRecord 应该有一条记录");
			Logger.verifyEquals(catalogStockListDto.getActivityId(), ymtActivityStockRecordList.get(0).getActivityId(), "SQL-Ymt_ActivityStockRecord activityId 检查");
			Logger.verifyEquals(catalogStockListDto.getStockNum(), ymtActivityStockRecordList.get(0).getChangeStock(), "SQL-Ymt_ActivityStockRecord changestock 检查");
			Logger.verifyEquals(catalogStockListDto.getProductId(), ymtActivityStockRecordList.get(0).getProductId(), "SQL-Ymt_ActivityStockRecord productId 检查");
			Logger.verifyEquals(catalogStockListDto.getCatalogId(), ymtActivityStockRecordList.get(0).getCatalogId(), "SQL-Ymt_ActivityStockRecord CatalogId 检查");
			
		}
		//mongo
		checkStockInMgo(catalogStockListDto.getCatalogId(),catalogStockListDto.getActivityId(),expectedStock,expectedActivityStock);
		
		//es check
		EsProductCallService.checkEsProduct(catalogStockListDto.getProductId());
		
		
	}
	
	public static void checkBackStock2(CatalogStockListDto catalogStockListDto,int expectedStock, int expectedActivityStock,boolean returnSuccess,long orderId) throws Exception{
		//sql
		//check ymt_catalogId inum
		YmtCatalogsIWapper ymtCatalogsIWapper = new YmtCatalogsIWapper();
		YmtCatalogsI catalogInSql = ymtCatalogsIWapper.selectCatalogsByCatalogId(catalogStockListDto.getCatalogId());
		Logger.verifyEquals(expectedStock, catalogInSql.getiNum(),  "SQL-Ymt_Catalogs 商品库存数量");
		
		
		//sql 日志检查
		//check YmtProductOrderStockLog
		List<YmtProductOrderStockLog> ymtProductOrderStockLogList = new YmtProductOrderStockLogWapper().selectByOrderId(orderId);
		
		//check YmtPreOrderStockLogWapper
		List<YmtPreOrderStockLog> ymtPreOrderStockLogList = new YmtPreOrderStockLogWapper().selectByPreOrderId(orderId);
		if (returnSuccess){
			
			if (orderId==catalogStockListDto.getRefundBillNo()){
				//return for bill
				Logger.verifyEquals(1, ymtProductOrderStockLogList.size(), "SQL-Ymt_ProductOrderStockLog 应该有一条记录");
				Logger.verifyEquals(1, ymtPreOrderStockLogList.size(), "SQL-YmtPreOrderStockLog 应该有一条记录");
			}else{
				//return for order
				Logger.verifyEquals(2, ymtProductOrderStockLogList.size(), "SQL-Ymt_ProductOrderStockLog 应该有两条记录");
				Logger.verifyEquals(2, ymtPreOrderStockLogList.size(), "SQL-YmtPreOrderStockLog 应该有二条记录");
			}
			
			
			Logger.verifyEquals(catalogStockListDto.getStockNum(),ymtProductOrderStockLogList.get(0).getStockNum(), "SQL-Ymt_ProductOrderStockLog stock 检查");
			Logger.verifyEquals(catalogStockListDto.getBuyerId(),ymtProductOrderStockLogList.get(0).getBuyerId(),  "SQL-Ymt_ProductOrderStockLog buyId 检查");
		
			
			Logger.verifyEquals(1, ymtPreOrderStockLogList.get(0).getOperType(), "SQL-YmtPreOrderStockLog operType应该为1");
			
			//活动库存额外查
			if (catalogStockListDto.getActivityId()>0){
				Logger.verifyEquals(catalogStockListDto.getActivityId(),ymtProductOrderStockLogList.get(0).getActivityId(), "SQL-Ymt_ProductOrderStockLog activityId 检查");
			}else{
				Logger.verifyEquals(0,ymtProductOrderStockLogList.get(0).getActivityId(), "SQL-Ymt_ProductOrderStockLog activityId 检查");
			}
			
			
	
			
			
		}else{
			Logger.verifyEquals(0, ymtProductOrderStockLogList.size(), "YmtProductOrderStockLog - 下单失败不应有记录");
			Logger.verifyEquals(0, ymtPreOrderStockLogList.size(),"YmtPreOrderStockLogWapper - 下单失败不应有记录");
		}
		
		
		//普通贝海商品 检查在途库存 Ymt_StockChangeDetail
		if (catalogStockListDto.getCatalogType()==2&&catalogStockListDto.getActivityId()==0){
			List<YmtProductOrderStockLog> ymtProductOrderStockLogList1 = new YmtProductOrderStockLogWapper().selectByCatalogId(catalogStockListDto.getCatalogId());
			int sum_OrderNum = ymtProductOrderStockLogList1.stream().filter(x->x.getActivityId()==0).map(y->y.getStockNum()).collect(Collectors.summingInt(Integer::intValue));
		
			YmtStockChangeDetailWapper ymtStockChangeDetailWapper = new YmtStockChangeDetailWapper();
			List<YmtStockChangeDetail> ymtStockChangeDetailList = ymtStockChangeDetailWapper.selectByCatalogId(catalogStockListDto.getCatalogId());
			
			Logger.verifyEquals(1, ymtStockChangeDetailList.size(),"SQL-Ymt_StockChangeDetail 记录个数应有1条");
			Logger.verifyEquals(-1*sum_OrderNum, ymtStockChangeDetailList.get(0).getiStock(), "SQL-Ymt_StockChangeDetail stock");
			Logger.verifyEquals(catalogInSql.getsSKU(), ymtStockChangeDetailList.get(0).getsSKU(), "SQL-Ymt_StockChangeDetail sku");
		}
	
		
		
		//活动商品
		if (catalogStockListDto.getActivityId()>0){
			YmtProductActivityStockWapper ymtProductActivityStockWapper = new YmtProductActivityStockWapper();
			YmtProductActivityStock ymtProductActivityStock = ymtProductActivityStockWapper.selectByCatalogId(catalogStockListDto.getCatalogId());
			Logger.verifyEquals(expectedActivityStock, ymtProductActivityStock.getIstocknum(), "SQL-YmtProductActivityStock stock 检查");
			Logger.verifyEquals(catalogStockListDto.getActivityId(),ymtProductActivityStock.getIactivityid(), "SQL-YmtProductActivityStock activityId 检查");
		
			//Ymt_ActivityStockRecord 检查
			List<YmtActivityStockRecord> ymtActivityStockRecordList = new YmtActivityStockRecordWapper().
									selectByOrderIdAndProdInActivityId(orderId, ymtProductActivityStock.getIproductinactivityid());
			
			//Logger.verifyEquals(1, ymtActivityStockRecordList.size(), "Ymt_ActivityStockRecord 应该有一条记录");
			Logger.verifyEquals(catalogStockListDto.getActivityId(), ymtActivityStockRecordList.get(0).getActivityId(), "SQL-Ymt_ActivityStockRecord activityId 检查");
			Logger.verifyEquals(catalogStockListDto.getStockNum(), ymtActivityStockRecordList.get(0).getChangeStock(), "SQL-Ymt_ActivityStockRecord changestock 检查");
			Logger.verifyEquals(catalogStockListDto.getProductId(), ymtActivityStockRecordList.get(0).getProductId(), "SQL-Ymt_ActivityStockRecord productId 检查");
			Logger.verifyEquals(catalogStockListDto.getCatalogId(), ymtActivityStockRecordList.get(0).getCatalogId(), "SQL-Ymt_ActivityStockRecord CatalogId 检查");
			
		}
		//mongo
		checkStockInMgo(catalogStockListDto.getCatalogId(),catalogStockListDto.getActivityId(),expectedStock,expectedActivityStock);
		
		//es check
		EsProductCallService.checkEsProduct(catalogStockListDto.getProductId());
		
		
	}
	
	public static void checkReturnStock(CatalogStockListDto catalogStockListDto,int expectedStock, int expectedActivityStock,boolean returnSuccess) throws Exception{
		checkBackStock2(catalogStockListDto,expectedStock,expectedActivityStock,returnSuccess,catalogStockListDto.getOrderId());
	}
	
	
	public static void checkReturnStockForBill(CatalogStockListDto catalogStockListDto,int expectedStock, int expectedActivityStock,boolean returnSuccess) throws Exception{
		checkBackStock(catalogStockListDto,expectedStock,expectedActivityStock,returnSuccess,catalogStockListDto.getRefundBillNo());
	}
	
	
	
	private static void checkStockInMgo(String catalogId,int activityId, int expectedStock, int expectedActivityStock) throws Exception{
		
		
		//mongo
		if (YmtMongoDriverFactroy.isNewJavaMgoCheck()){
			if (new YmtCatalogsIWapper().selectCatalogsByCatalogIdforList(catalogId).get(0).getiAction()<0){return;}
			
			CatalogsWapper catalogsWapper = new CatalogsWapper();
			Map<String,Object> catalogsMap = catalogsWapper.getByCatalogId(catalogId);
			Logger.verifyEquals(expectedStock, Integer.parseInt(catalogsMap.get("stock").toString()), "Mongo-Catalogs stock 检查");
			
			//活动商品检查
			if (activityId>0){
				ActivityProductsWapper activityProductsWapper = new ActivityProductsWapper();
				Map<String,Object> prodInActMgoMap = activityProductsWapper.getByProdId(catalogsMap.get("spid").toString());
				Logger.verifyEquals(activityId, Integer.parseInt(prodInActMgoMap.get("aid").toString()), "Mongo-ActivityProducts activityId 检查");
				
				JSONArray catalogsAry = new JSONArray(prodInActMgoMap.get("catalogs").toString());
				boolean isFoundCatalog = false;
				for(int i=0;i<catalogsAry.length();i++){
					if (catalogsAry.getJSONObject(i).getString("cid").equals(catalogId)){
						Logger.verifyEquals(expectedActivityStock, catalogsAry.getJSONObject(i).getInt("stock"), "Mongo-ActivityProducts stock 检查");
						isFoundCatalog = true;
						break;
					}
				}
				Logger.verifyEquals(true, isFoundCatalog, "Mongo-ActivityProducts 应该存在规格:"+catalogId);
			}
			
		}
		
	}
	
	
	
	
	// limitType 0:活动限购, 1:活动商品限购
	public static void updateActivityLimit(int activityId, int limitType,int limitNum) throws Exception{
		//update sql
		YmtActivityWapper ymtActivityWapper = new YmtActivityWapper();
		int sqlRet = ymtActivityWapper.updateActivityLimit(activityId, limitType, limitNum);
		String ret = sqlRet>0?"成功":"失败";
		Logger.comment("sql activityId:"+activityId+", 限购数据修改,"+ ret );
		
		//update mongo
		if (YmtMongoDriverFactroy.isNewJavaMgoCheck()){
			ActivityProductsWapper activityProductsWapper = new ActivityProductsWapper();
			if (limitType ==0){
				String retMgo = activityProductsWapper.update(MapUtil.hashMap("aid",activityId),MapUtil.hashMap("alimit", limitNum))?"成功":"失败";
				Logger.comment("Mongo activityId:"+activityId+", 限购数据修改,"+ retMgo );
			}else{
				String retMgo = activityProductsWapper.update(MapUtil.hashMap("aid",activityId),MapUtil.hashMap("plimit", limitNum))?"成功":"失败";
				Logger.comment("Mongo activityId:"+activityId+", 限购数据修改,"+ retMgo );
			}
			
		}
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	private static long getCurrentOrderId(){
	/*	YmtOrdersWapper ymtOrdersWapper = new YmtOrdersWapper();
		int iOrder=0;
		try {
			iOrder = ymtOrdersWapper.selectEarlyOrderInfo().getIorderid();
			ymtOrdersWapper.updateOrderAddtimeByOrderId(iOrder, 0);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}*/
		return System.currentTimeMillis();
	}
}
